import EditOutlined from '@material-ui/icons/EditOutlined';
import OutlinedInput from '@material-ui/core/OutlinedInput';
import InputLabel from '@material-ui/core/InputLabel';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
import InputAdornment from '@material-ui/core/InputAdornment';
import SearchIcon from '@material-ui/icons/Search';
import IconButton from '@material-ui/core/IconButton';
import { TextWhite } from '../base/st';
import TextField from '@material-ui/core/TextField';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import React, { useMemo, useState, useEffect } from 'react';
import { loc,Btn, ErrView, Dlg, obj_bool, obj_str, is_empty } from 'sui';
import { MaTable } from './table';

/* hcmd: hcmd(name, value)
 * hkey: hkey(k)
 * href:
 *  const uref = useRef(null)
 *  uref.current.focus();
 *  href={uref}
*/
const WhiteInput = ({ mg, disabled=false, value, label, name, type="text", href, hcmd, hkey }) => <TextWhite
    className="w-full"
    variant="outlined"
    disabled={disabled}
    name={name}
    type={type}
    value={value ? value : ""}
    inputRef={href}
    margin={mg}
    onChange={hcmd ? ({ target:{ name, value }}) => hcmd(name, value) : null}
    onKeyPress={hkey ? (v) => hkey(v.key) : null}
    label={label}/>;

/* hcmd: hcmd(name, value)
 * hkey: hkey(k)
 * href:
 *  const uref = useRef(null)
 *  uref.current.focus();
 *  href={uref}
 * mg: dense
*/
const Input = ({ disabled=false, value, label, name, type="text", href, hcmd, hkey, mg="normal", width="w-64", auto }) => {
    const handle = (event) => {
        if (hcmd) {
            hcmd(event.target.name, event.target.value);
        }
    };

    const handleKey = (event) => {
        if (hkey) {
            hkey(event.key);
        }
    };

    return <TextField
        autoComplete={auto}
        disabled={disabled}
        className={width}
        margin={mg}
        variant="outlined"
        name={name}
        type={type}
        value={value}
        inputRef={href}
        onChange={handle}
        onKeyPress={handleKey}
        label={label}/>;
};

const IkInput = ({ className, form, value, label, name, width="w-64", mg="normal", disabled, type="text", href, mul=false }) => {
    const [err, setErr] = useState(false);
    const [err_txt, errTxt] = useState("");

    useEffect(() => {
        const e = obj_str(form.err, name);
        if (e === err_txt) {
            return;
        }

        if (e) {
            setErr(true);
            errTxt(e);
        }
        else {
            setErr(false);
            errTxt("");
        }
    }, [name, form.err, err_txt]);

    if (mul) {
        return (
            <div className={className}>
                <TextField
                    multiline
                    disabled={disabled}
                    margin={mg}
                    variant="outlined"
                    type={type}
                    className={width}
                    name={name}
                    error={err}
                    helperText={err_txt}
                    value={obj_str(value, name)}
                    inputRef={href}
                    onChange={event => form.hcmd(event.target.name, event.target.value)}
                    label={label}/>
            </div>
        );
    }

    return (
        <div className={className}>
            <TextField
                disabled={disabled}
                margin={mg}
                variant="outlined"
                type={type}
                className={width}
                name={name}
                error={err}
                helperText={err_txt}
                value={obj_str(value, name)}
                inputRef={href}
                onChange={event => form.hcmd(event.target.name, event.target.value)}
                label={label}/>
        </div>
    );
};

const IkCheck = ({ name, label, value, form, className }) => {
    const [val, setVal] = useState(false);

    useEffect(() => {
        const e = obj_bool(value, name);
        if (val === e) {
            return;
        }

        setVal(e);
    }, [name, value, val]);

    const hchg = (event) => form.hcmd(name, event.target.checked);

    return (
        <div className={className}>
            <FormGroup row>
                <FormControlLabel
                    control={<Checkbox color="primary" name={name} checked={obj_bool(value, name)} onChange={hchg} value={name}/>}
                    label={label}/>
            </FormGroup>
        </div>
    );
};

/*
 * lst = [
 *     {id: "x", sn: "x", name: "x"}
 * ]
 */
const IkFind = ({ hcmd, className, form, value, label, name, width="w-64", dlgw="md", dlgst="", mg="normal", fullWidth=true, lst, col }) => {
    const [open, setOpen] = useState(false);
    const [row, setRow] = useState();
    const [cur, setCur] = useState();
    const [err, setErr] = useState();

    useEffect(() => {
        if (!open) {
            return;
        }

        if (is_empty(lst)) {
            return;
        }

        setCur(obj_str(value, name));
        setRow(lst);
        setErr("");
    }, [open, lst, name, value]);

    const getView = useMemo(() => {
        if (!open) {
            return null;
        }

        const getCl = (d) => {
            if (cur === d.id) {
                return "#FEEBC8";   // orange-200
            }

            return '#FFF';
        };

        const getCol = () => {
            if (col) {
                return col;
            }

            return [
                {title: loc("l_495"), field: 'sn'},
                {title: loc("l_189"), field: 'name'},
            ];
        };

        return (
            <MaTable
                title={<ErrView err={err}/>}
                opt={{
                    rowStyle: d => ({
                        backgroundColor: getCl(d)
                    }),
                }}
                hclick={(v) => setCur(v.id)}
                page={7}
                col={getCol()}
                row={row}
                exbt={false} />
        );
    }, [open, col, err, row, cur]);

    const hdone = () => {
        if (!cur) {
            return;
        }

        setOpen(false);
        form.hcmd(name, cur);

        if (hcmd) {
            hcmd(cur);
        }
    };

    const getVal = () => {
        if (is_empty(lst)) {
            return "";
        }

        const id = obj_str(value, name);
        const f = lst.find(d => d.id === id);
        if (!f) {
            return "";
        }

        let v = obj_str(f, "sn");
        const t = obj_str(f, "name");
        if (t) {
            v = `${v} ( ${t} )`;
        }

        return v;
    };

    const getInfo = () => {
        const info = obj_str(form.err, name);
        if (info) {
            return <FormHelperText>{info}</FormHelperText>;
        }

        return null;
    };

    const sz = mg === "dense" ? "small" : "medium";

    return (
        <div className={className}>
            <FormControl margin={mg} variant="outlined" className={width} error={Boolean(form.err[name])}>
                <InputLabel>{label}</InputLabel>
                <OutlinedInput
                    disabled={true}
                    name={name}
                    type="text"
                    value={getVal()}
                    endAdornment={
                        <InputAdornment position="end">
                            <IconButton size={sz} onClick={() => setOpen(true)} name={`btn${name}`}>
                                <SearchIcon fontSize={sz}/>
                            </IconButton>
                        </InputAdornment>
                    }
                    label={label}
                />
                {getInfo()}
            </FormControl>
            <Dlg open={open} hcancel={() => setOpen(false)} title={label} hcmd={hdone} width={dlgw} fullWidth={fullWidth} name={`bt${name}`}>
                {getView}
            </Dlg>
        </div>
    );
};

/*
 * lst = [
 *     {id: "x", sn: "x", name: "x"}
 * ]
 */
const Ifind = ({ hcmd, className, setValue, value, label, name, width="w-64", dlgw="md", dlgst="", mg="normal", fullWidth=true, lst, col }) => {
    const [open, setOpen] = useState(false);
    const [row, setRow] = useState();
    const [cur, setCur] = useState();
    const [err, setErr] = useState();

    useEffect(() => {
        if (!open) {
            return;
        }

        if (is_empty(lst)) {
            return;
        }

        setCur(value);
        setRow(lst);
        setErr("");
    }, [open, lst, name, value]);

    const getView = useMemo(() => {
        if (!open) {
            return null;
        }

        const getCl = (d) => {
            if (cur === d.id) {
                return "#FEEBC8";   // orange-200
            }

            return '#FFF';
        };

        const getCol = () => {
            if (col) {
                return col;
            }

            return [
                {title: loc("l_495"), field: 'sn'},
                {title: loc("l_189"), field: 'name'},
            ];
        };

        return (
            <MaTable
                title={<ErrView err={err}/>}
                opt={{
                    rowStyle: d => ({
                        backgroundColor: getCl(d)
                    }),
                }}
                hclick={(v) => setCur(v.id)}
                page={7}
                col={getCol()}
                row={row}
                exbt={false} />
        );
    }, [open, col, err, row, cur]);

    const hdone = () => {
        if (!cur) {
            return;
        }

        setOpen(false);
        setValue(cur);

        if (hcmd) {
            hcmd(cur);
        }
    };

    const getVal = () => {
        if (is_empty(lst)) {
            return "";
        }

        const id = value;
        const f = lst.find(d => d.id === id);
        if (!f) {
            return "";
        }

        let v = obj_str(f, "sn");
        const t = obj_str(f, "name");
        if (t) {
            v = `${v} ( ${t} )`;
        }

        return v;
    };

    const sz = mg === "dense" ? "small" : "medium";

    return (
        <div className={className}>
            <FormControl margin={mg} variant="outlined" className={width}>
                <InputLabel>{label}</InputLabel>
                <OutlinedInput
                    disabled={true}
                    name={name}
                    type="text"
                    value={getVal()}
                    endAdornment={
                        <InputAdornment position="end">
                            <IconButton size={sz} onClick={() => setOpen(true)} name={`btn${name}`}>
                                <SearchIcon fontSize={sz}/>
                            </IconButton>
                        </InputAdornment>
                    }
                    label={label}
                />
            </FormControl>
            <Dlg open={open} hcancel={() => setOpen(false)} title={label} hcmd={hdone} width={dlgw} fullWidth={fullWidth} name={`bt${name}`}>
                {getView}
            </Dlg>
        </div>
    );
};

const IkCmd = ({ hcmd, className, form, value, label, name, width="w-64", mg="normal" }) => {
    const sz = mg === "dense" ? "small" : "medium";

    const getInfo = () => {
        const info = obj_str(form.err, name);
        if (info) {
            return <FormHelperText>{info}</FormHelperText>;
        }

        return null;
    };

    return (
        <div className={className}>
            <FormControl margin={mg} variant="outlined" className={width} error={Boolean(form.err[name])}>
                <InputLabel>{label}</InputLabel>
                <OutlinedInput
                    disabled={true}
                    name={name}
                    type="text"
                    value={obj_str(value, name)}
                    endAdornment={
                        <InputAdornment position="end">
                            <IconButton size={sz} onClick={hcmd} name={`btn${name}`}>
                                <SearchIcon fontSize={sz}/>
                            </IconButton>
                        </InputAdornment>
                    }
                    label={label}
                />
                {getInfo()}
            </FormControl>
        </div>
    );
};

/*
 * lst = [
 *     {id: "x", sn: "x", name: "x"}
 * ]
 */
const BtFind = ({ hcmd, className, label, name, width="w-64", dlgw="md", dlgst="", fullWidth=true, lst, col }) => {
    const [open, setOpen] = useState(false);
    const [row, setRow] = useState();
    const [cur, setCur] = useState();
    const [err, setErr] = useState();

    useEffect(() => {
        if (!open) {
            return;
        }

        if (is_empty(lst)) {
            return;
        }

        setRow(lst);
        setErr("");
    }, [open, lst, name]);

    const getView = useMemo(() => {
        if (!open) {
            return null;
        }

        const getCl = (d) => {
            if (cur === d.id) {
                return "#FEEBC8";   // orange-200
            }

            return '#FFF';
        };

        const getCol = () => {
            if (col) {
                return col;
            }

            return [
                {title: loc("l_495"), field: 'sn'},
                {title: loc("l_189"), field: 'name'},
            ];
        };

        return (
            <MaTable
                title={<ErrView err={err}/>}
                opt={{
                    rowStyle: d => ({
                        backgroundColor: getCl(d)
                    }),
                }}
                hclick={(v) => setCur(v.id)}
                page={7}
                col={getCol()}
                row={row}
                exbt={false} />
        );
    }, [open, col, err, row, cur]);

    const hdone = () => {
        if (!cur) {
            return;
        }

        setOpen(false);

        if (hcmd) {
            hcmd(cur);
        }
    };

    return (
        <div className={className}>
            <Btn hcmd={() => setOpen(true)}>{label}</Btn>
            <Dlg open={open} hcancel={() => setOpen(false)} title={label} hcmd={hdone} width={dlgw} fullWidth={fullWidth} name={`bt${name}`}>
                {getView}
            </Dlg>
        </div>
    );
};

const IconInput = ({ className, form, value, label, name, width="w-64", mg="normal", disabled, hcmd }) => {
    const getInfo = () => {
        const info = obj_str(form.err, name);
        if (info) {
            return <FormHelperText>{info}</FormHelperText>;
        }

        return null;
    };

    const sz = mg === "dense" ? "small" : "medium";

    return (
        <div className={className}>
            <FormControl margin={mg} variant="outlined" className={width} error={Boolean(form.err[name])}>
                <InputLabel>{label}</InputLabel>
                <OutlinedInput
                    disabled={true}
                    name={name}
                    type="text"
                    value={obj_str(value, name)}
                    onChange={event => form.hcmd(event.target.name, event.target.value)}
                    endAdornment={
                        <InputAdornment position="end">
                            <IconButton size={sz} onClick={() => hcmd()} name={`btn${name}`} disabled={disabled}>
                                <EditOutlined fontSize={sz}/>
                            </IconButton>
                        </InputAdornment>
                    }
                    label={label}
                />
                {getInfo()}
            </FormControl>
        </div>
    );
};

export {IconInput, BtFind, IkCmd, Ifind, IkFind, IkCheck, IkInput, Input, WhiteInput};
